home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / video / xevil-1.000 / xevil-1 / ui.h < prev    next >
C/C++ Source or Header  |  1995-07-10  |  17KB  |  533 lines

  1. // "ui.h"  Header for user interface module.  
  2.  
  3. /*    Copyright (C) 1994  Steve Hardt
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 1, or (at your option)
  8.     any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19.     Steve Hardt 
  20.     hardts@athena.mit.edu hardts@media.mit.edu
  21.     hardts@r4002.3dem.bioch.bcm.tmc.edu
  22.     2043 McClendon
  23.     Houston, TX 77030
  24. */
  25.  
  26. /* Overview:
  27.    Draws the world.  Manages viewports.  Holds x variables.  Follows an intel
  28. if one is registered.  Sends commands to the intel if it is human.  For weapon
  29. commands, tapping key gives most recently pressed direction or IT_CENTER if 
  30. there is none. */
  31.  
  32. /* NOTE: A Ui is never destroyed.  Allocates memory for transfering to 
  33.      callbacks and event handlers. */
  34.  
  35. #ifndef UI_H  //Make sure that file is not included more than once.
  36. #define UI_H
  37.  
  38. #ifndef NO_PRAGMAS
  39. #pragma interface
  40. #endif
  41.  
  42.  
  43. // Include Files
  44. #include "utils.h"
  45. #include "coord.h"
  46. #include "world.h"
  47. #include "locator.h"
  48. #include "id.h"
  49. #include "intel.h"
  50.  
  51.  
  52.  
  53. // Defines
  54. #define UI_VIEWPORTS_MAX 10
  55. #define UI_KEYS_MAX IT_WEAPON_R
  56. #define UI_STRING_LENGTH 600 // For panels.
  57. #define UI_STATUSES_NUM 8  // Not 9, because ammo is with weapon.
  58. #define UI_MENUS_PRIMARY_NUM 15
  59. #define UI_MENUS_SECONDARY_NUM 2
  60. #define UI_SHORT_STRING_LENGTH 80
  61.  
  62.  
  63. // Data Structures
  64. enum UIinput {UI_KEYS_RIGHT,UI_KEYS_LEFT};
  65. enum UIkeyset {UIsun3, UIdecmips, UIiris, UIncd, UItektronix, UIsun4, UIrsaix,
  66.            UIsun4_sparc,UImac,UIalpha};
  67.  
  68. class Ui;
  69. typedef Ui *UiP;
  70.  
  71. // First index is an IT_COMMAND, sedond is one of two.
  72. typedef KeySym UIkeymap[UI_KEYS_MAX][2];
  73.  
  74. typedef unsigned long UImask;
  75. #define UInone 0L
  76. #define UInewGame (1L<<0)
  77. #define UIquit (1L<<1)
  78. #define UIhumansNum (1L<<2)
  79. #define UIenemiesNum (1L<<3)
  80. #define UIenemiesRefill (1L<<4)
  81. #define UIpause (1L<<6)
  82. #define UIstyle (1L<<7)
  83. #define UIquanta (1L<<8)
  84.  
  85. class UIsettings {
  86. public:
  87.   enum Style {SCENARIOS,LEVELS,KILL,DUEL,EXTENDED,TRAINING};
  88.  
  89.   int humansNum;
  90.   int enemiesNum;
  91.   Boolean enemiesRefill;
  92.   Boolean pause;
  93.   Style style;
  94.   Quanta quanta;
  95. };
  96.  
  97.  
  98.  
  99. // Class Declarations
  100. class TextPanel;
  101. class TogglePanel;
  102. class KeyPressPanel;
  103.  
  104. class Ui {
  105.   struct UIxdata {
  106.     Window controls[Xvars::DISPLAYS_MAX];
  107.     
  108.     // The top level shell containing the KeyPressPanel.
  109.     Window learnControls[Xvars::DISPLAYS_MAX]; 
  110.     Window toplevels[UI_VIEWPORTS_MAX];
  111.     Window arenas[UI_VIEWPORTS_MAX];
  112.     Cursor arenaCursor[Xvars::DISPLAYS_MAX];
  113.     Pixmap icon[Xvars::DISPLAYS_MAX];
  114.   };
  115.   
  116.   
  117.  public:
  118.   Ui(int *argc,char **argv,WorldP w,LocatorP l,
  119.      char **displayNames,Boolean polCorrect);  
  120.   /* EFFECTS: Create user interface with one viewport (number 0) with world w 
  121.      and locator l.  The memory pointed to by displayNames becomes the
  122.      property of the Ui. */
  123.   /* NOTE: Must set_keyset on all displays before first clock. 
  124.      Must manually set_* all desired parameters before first reset. */
  125.  
  126.   int get_viewports_num() {return viewportsNum;}
  127.   /* EFFECTS: Total number of viewports in the Ui. */
  128.  
  129.   int get_viewports_num_on_dpy(int dpyNum) {return vIndexNum[dpyNum];}
  130.   int get_viewport_on_dpy(int dpyNum,int v) {return vIndex[dpyNum][v];}
  131.   /* EFFECTS: Get viewports and number of viewports on a single display.
  132.      The viewports on a display, dpyNum, range from 0 to 
  133.      get_viewports_num_on(dpyNum) - 1. */
  134.  
  135.   Display *get_dpy(int dpyNum) {return xvars.dpy[dpyNum];}
  136.   int get_dpy_max() {return xvars.dpyMax;}
  137.   int get_dpy_num(int viewportNum) {return dpyIndex[viewportNum];}
  138.   /* EFFECTS: Display number from viewport Number. */
  139.  
  140.   UImask get_settings(UIsettings &s);
  141.   /* MODIFIES: s */
  142.   /* EFFECTS:  Get all of the settings that are stored in the Ui.  Mostly the
  143.      menubar stuff.  settingsChanges gives the fields in s that have changed
  144.      since the last call of get_settings.  Other fields are not guaranteed to
  145.      be meaningful.  Initially, nothing is changed. */
  146.  
  147.   const char * const *get_keys_names() 
  148.   {return (const char * const *)keysNames;}
  149.  
  150.   Boolean settings_changed() {return settingsChanges != UInone;}
  151.   /* EFFECTS:  Tells whether the the settings have changed since the last 
  152.      call of get_settings().  Initially is False. */
  153.  
  154.   Boolean keyset_set(int dpyNum) {return keysetSet[dpyNum];}
  155.  
  156.   void set_humans_num(int);
  157.   void set_enemies_num(int);
  158.   void set_enemies_refill(Boolean);
  159.   void set_style(UIsettings::Style);
  160.   void set_quanta(Quanta);
  161.  
  162.   void set_humans_playing(int);
  163.   void set_enemies_playing(int);
  164.  
  165.   void set_level(const char *);
  166.  
  167.   Boolean other_input() {return otherInput;}
  168.   /* EFFECTS: Tells whether there has been any keyboard or mouse press other
  169.      than a valid control since the last clock. */
  170.  
  171.   void set_input(int vNum,UIinput input);
  172.   /* EFFECTS: Set the input device for viewport num. */
  173.  
  174.   void set_keyset(int dpyNum,UIkeyset keyset);
  175.   void set_keyset(int dpyNum,UIkeyset basis,KeySym right[UI_KEYS_MAX][2],
  176.           KeySym left[UI_KEYS_MAX][2]);
  177.   /* REQUIRES: Must be called at least once before the first clock. */
  178.   /* IMPLEMENTATION NOTE: Sets keycodes[0 and 1] */
  179.  
  180.   void set_pause(Boolean);
  181.   /* EFFECTS: Pause/unpause. */
  182.  
  183.   void set_level_title(char *msg);
  184.   void unset_level_title();
  185.   /* EFFECTS: When set, the Ui will draw msg in every viewport,
  186.      until unset.  The world and locator are not drawn again until 
  187.      unset. */
  188.   /* NOTE: Takes care of Ui::set_redraw. */
  189.  
  190.   int add_viewport();
  191.   /* EFFECTS: Add another viewport and return its number. */
  192.  
  193.   void del_viewport();
  194.   /* EFFECTS: Delete the highest numbered viewport. */
  195.  
  196.   void register_intel(int n, IntelP intel);
  197.   /* REQUIRES: intel is not already registered with a different viewport. */
  198.   /* EFFECTS: Registers the intel on viewport n.  The viewport will now 
  199.      follow the object represented by intel->get_id() and send commands to 
  200.      it if it is human. */
  201.  
  202.   void unregister_intel(int n);
  203.   /* REQUIRES: n is a valid viewport */
  204.   /* EFFECTS: Unregister the intel associated with viewport n, if any.  
  205.      Otherwise do nothing. */
  206.  
  207.   void reset();
  208.   /* EFFECTS: Clear out all registered intels.  Does NOT remove viewports. */
  209.  
  210.   void set_redraw();
  211.   /* EFFECTS: Next turn, the Ui must redraw everything. */
  212.  
  213.   void process_event(int dpyNum,XEvent *event);
  214.   /* NOTE: Call callback last so that callback can make changes to self. */
  215.  
  216.   void clock();
  217.   /* EFFECTS: Follows the object of the registered intel if any and redraws 
  218.      the world and locator. */
  219.  
  220.   /* Must use static functions for callbacks because of problems with
  221.      pointers to member functions in some compilers. */
  222.   static void menu_quit_CB(UiP,int,int);
  223.   static void menu_new_game_CB(UiP,int,int);
  224.   static void menu_humans_num_CB(UiP,const char *value);
  225.   static void menu_enemies_num_CB(UiP,const char *value);
  226.   static void menu_enemies_refill_CB(UiP,TogglePanel *,Boolean val);
  227.   static void menu_controls_CB(UiP,TogglePanel *,Boolean);
  228.   static void menu_learn_controls_CB(UiP,TogglePanel *,Boolean);
  229.   static void menu_scenarios_CB(UiP,TogglePanel *,Boolean);
  230.   static void menu_levels_CB(UiP,TogglePanel *,Boolean);
  231.   static void menu_kill_CB(UiP,TogglePanel *,Boolean);
  232.   static void menu_duel_CB(UiP,TogglePanel *,Boolean);
  233.   static void menu_extended_CB(UiP,TogglePanel *,Boolean);
  234.   static void menu_training_CB(UiP,TogglePanel *,Boolean);
  235.   static void menu_quanta_CB(UiP,const char *value);
  236.  
  237.   static void status_weapon_CB(UiP,int,int);
  238.   static void status_item_CB(UiP,int,int);
  239.  
  240.   static void learn_controls_CB(UiP,KeyPressPanel *,XEvent *);
  241.  
  242.  
  243.  private:
  244.   void set_message(const char *message);
  245.   /* EFECTS: Places message on all the viewports' message bars.  */
  246.  
  247.   void draw(int viewportNum, Boolean changedOnly = False);
  248.   /* REQUIRES: viewportNum is valid. */
  249.   /* EFFECTS: Draw everything in viewport number num. */
  250.  
  251.   void init_x();
  252.   /* EFFECTS: Initialize the X Window variables in the Ui. */
  253.   /* NOTE: Also sets vIndex,vIndexMax,meunusNum,dpyIndex. */
  254.  
  255.   void init_sizes();
  256.  
  257.   Boolean viewport_to_loc(int n,const Loc &l);
  258.   /* REQUIRES: n is a valid viewport num.  l is a location in the world. */
  259.   /* EFFECTS: Moves viewport n so that l is in it.  Returns True iff the
  260.    viewport has moved. */
  261.  
  262.   void dispatch(int v,ITcommand command);
  263.   /* EFFECTS: Let viewport v deal with the given command.  I.e. Send it to a 
  264.      intel or move the viewport around. */
  265.  
  266.   int get_viewport_num(int dpyNum,Window window);
  267.   /* EFFECTS: If window is one of the arenas, returns the viewport num.  
  268.      Otherwise, returns -1. */
  269.  
  270.   void create_controls();
  271.  
  272.   void create_learn_controls();
  273.  
  274.   void create_toplevel(int viewportNum);
  275.   /* EFFECTS: Create a top-level window, set the input mask, set standard WM
  276.      properties, and map it.  Creates menus, arena, statuses, intelsPlaying,
  277.      and messageBar.  If viewportNum == 0 then it creates the menus. */
  278.  
  279.   void create_menus(int viewportNum);
  280.   void create_arena(int viewportNum);
  281.   void create_statuses(int viewportNum);
  282.   void create_intels_playing(int viewportNum);
  283.   void create_message_bar(int viewportNum);
  284.   void create_levels(int viewportNum);
  285.  
  286.   void update_statuses(int viewportNum);
  287.  
  288.   void controls_redraw(int dpyNum);
  289.  
  290.   // Events taking place on viewports.
  291.   void viewport_expose(int viewportNum); 
  292.   void viewport_key_press(int dpyNum,XEvent *event);
  293.   void viewport_key_release(int dpyNum,XEvent *event);
  294.   void viewport_button_press(int viewportNum,XEvent *event);
  295.   Boolean viewport_button_press_helper(Dir &dir,int viewportNum,
  296.                        XEvent *event);
  297.   Dir key_press_to_dir(int dpyNum,XEvent *event);
  298.  
  299.   void controls_expose(int dpyNum,XEvent *) {controls_redraw(dpyNum);}
  300.  
  301.  
  302.   // Variables.
  303.   static char *keysNames[UI_KEYS_MAX];
  304.  
  305.   char **argv;  // Warning: Exposing the rep.
  306.   int argc;
  307.   Xvars xvars;
  308.   UIxdata xdata;
  309.   char **displayNames;  /* Array of [UI_VIEWPORTS_MAX]. 
  310.                Warning: Exposing the rep. */
  311.  
  312.   int viewportsNum;  // Total number of viewports on all displays.
  313.   int dpyIndex[UI_VIEWPORTS_MAX]; // Map from viewports to displays.
  314.  
  315.   // Map from displays to viewports, a one to many map.
  316.   int vIndex[Xvars::DISPLAYS_MAX][UI_VIEWPORTS_MAX]; 
  317.   int vIndexNum[Xvars::DISPLAYS_MAX]; //Current number of viewports on a display.
  318.   int vIndexMax[Xvars::DISPLAYS_MAX]; //Possible number of viewports on a display.
  319.  
  320.   WorldP world;
  321.   LocatorP locator;
  322.   Box viewportBoxes[UI_VIEWPORTS_MAX];
  323.   Boolean intelsSet[UI_VIEWPORTS_MAX];
  324.   IntelP intels[UI_VIEWPORTS_MAX];
  325.  
  326.   // Meaningful iff keysetSet.
  327.   unsigned int keycodes[Xvars::DISPLAYS_MAX][2][UI_KEYS_MAX][2]; 
  328.   Boolean keysetSet[Xvars::DISPLAYS_MAX];
  329.  
  330.   UIinput inputs[UI_VIEWPORTS_MAX];  // Meaningful iff inputsSet[].
  331.   Boolean inputsSet[UI_VIEWPORTS_MAX];
  332.  
  333.   Dim roomDim;
  334.   UIsettings settings;
  335.   UImask settingsChanges;
  336.   Boolean otherInput;
  337.   Boolean cursorDefined[UI_VIEWPORTS_MAX];
  338.   Boolean weaponKeyDown[UI_VIEWPORTS_MAX];
  339.  
  340.   ITcommand weaponCommandDefault[UI_VIEWPORTS_MAX];
  341.  
  342.   Boolean neverReset; /* So can't scroll with title screen. */
  343.  
  344.   Size menusSize[Xvars::DISPLAYS_MAX];
  345.   Size roomSize[Xvars::DISPLAYS_MAX];
  346.   Size arenaSize[Xvars::DISPLAYS_MAX];
  347.   Size statusesSize[Xvars::DISPLAYS_MAX];
  348.   Size intelsPlayingSize[Xvars::DISPLAYS_MAX];
  349.   Size messageBarSize[Xvars::DISPLAYS_MAX];
  350.   Size viewportSize[Xvars::DISPLAYS_MAX];
  351.  
  352.   // Must redraw all Panels after Pause/Unpause.
  353.   TextPanel *menus[UI_VIEWPORTS_MAX][UI_MENUS_PRIMARY_NUM];
  354.   /* Takes advantage of fact that menuControls and menuLearnControls are
  355.      the first two elements of the enumeration. */
  356.   int menusNum[UI_VIEWPORTS_MAX]; 
  357.   TextPanel *statuses[UI_VIEWPORTS_MAX][UI_STATUSES_NUM];
  358.   TextPanel *humansPlaying[UI_VIEWPORTS_MAX];
  359.   TextPanel *enemiesPlaying[UI_VIEWPORTS_MAX];
  360.   TextPanel *messageBars[UI_VIEWPORTS_MAX];
  361.   TextPanel *levels[UI_VIEWPORTS_MAX];
  362.   Timer messageTimer;
  363.   Boolean redrawAll[UI_VIEWPORTS_MAX]; 
  364.   Boolean pause;
  365.   Boolean levelTitle; // The Ui is displaying the title of a level.
  366.   char levelTitleString[UI_SHORT_STRING_LENGTH];
  367.   Boolean polCorrect;
  368.   // The actual control learning panel.
  369.   KeyPressPanel *learnControls[Xvars::DISPLAYS_MAX];  
  370.  
  371.   struct LControls {
  372.     int input,key,which;
  373.   };
  374.   LControls lControls[Xvars::DISPLAYS_MAX];
  375. };
  376.  
  377.  
  378.  
  379. class Panel {
  380.  public:
  381.   Panel(UiP ui,int dpyNum,int viewportNum,const Xvars &,
  382.     Window,const Pos &,const Size &);
  383.   /* EFFECTS: Creatue a new panel at position pos of size size.  The positio
  384.      and size includes the border.  Color is initially black.  Use a 
  385.      viewportNum of -1 if there is no associated viewportNum. */
  386.   /* NOTE: Must explicity set dpyNum as a Panel may be created with 
  387.      viewportNum = -1. */
  388.  
  389.   UiP get_ui() {return ui;}
  390.  
  391.   Pixel get_foreground() {return foreground;}
  392.   Pixel get_background() {return background;}
  393.   Size get_size() {return size;}
  394.   Window get_window() {return window;}
  395.   const Xvars &get_xvars() {return xvars;}
  396.  
  397.   int get_viewport_num() {assert(viewportNum >= 0); return viewportNum;}
  398.   int get_dpy_num() {return dpyNum;}
  399.  
  400.   void set_foreground(Pixel c,Boolean re_draw = True);
  401.   void set_background(Pixel c,Boolean re_draw = True);
  402.   /* EFFECTS: Changes the color for the panel.  Redraws iff re_draw. */
  403.  
  404.   virtual Boolean process_event(int dpyNum,XEvent *event);
  405.   /* EFFECTS: Panel deals with the event if it applies.  Returns True iff it
  406.      used the event. */
  407.   /* NOTE: Only calls up the tree if event is not processed at current 
  408.      level. */
  409.  
  410.   virtual void redraw() = 0;
  411.   virtual void clear() = 0;
  412.  
  413.  
  414.  private:
  415.   const Xvars &xvars;
  416.   int dpyNum; // redundant.  Same as ui->get_dpy_num(viewportNum).
  417.   Window window;
  418.   int viewportNum;
  419.   Size size; // Inside the border.
  420.   Pixel foreground,background;
  421.   UiP ui;
  422. };
  423.  
  424.  
  425.  
  426. class TextPanel: public Panel {
  427.  public:
  428.   TextPanel(UiP ui,int dpyNum,int viewportNum,const Xvars &xvars,
  429.         Window parent,const Pos &pos,const Size &size,
  430.         const char *msg = NULL);
  431.   
  432.   void set_message(const char *msg);
  433.   /* NOTE:  Makes its own copy.  Redraws. */
  434.  
  435.   static Size get_unit(XFontStruct *,int cols,int rows = 1);
  436.  
  437.   virtual void redraw();
  438.   virtual void clear();
  439.   
  440.   void set_sensitive(Boolean val);
  441.   Boolean get_sensitive() {return sensitive;}
  442.  
  443.  
  444.  private:
  445.   char message[UI_STRING_LENGTH];
  446.   Boolean sensitive;
  447. };
  448.  
  449.  
  450.  
  451. class WritePanel : public TextPanel {
  452. /* OVERVIEW: Accepts text input.  Displays "<prompt><input>_" as its 
  453.    message. */
  454.  
  455.  public:
  456.   WritePanel(UiP ui,int dpyNum,int viewportNum,const Xvars &xvars,
  457.          Window parent,
  458.          const Pos &pos,const Size &size,
  459.          void (*callback)(UiP,const char *),
  460.          const char *prompt = NULL);
  461.   /* NOTE: prompt appears before the user's input text. */
  462.   
  463.   const char *get_value() {return value;}
  464.   void set_value(const char *value);
  465.  
  466.   virtual Boolean process_event(int dpyNum,XEvent *event);
  467.  
  468.  
  469.  private:
  470.   void update_message();
  471.  
  472.   Boolean active;
  473.   char prompt[UI_STRING_LENGTH];
  474.   char value[UI_STRING_LENGTH];
  475.   void (*callback)(UiP,const char *);
  476. };
  477.  
  478.  
  479.  
  480. class KeyPressPanel: public TextPanel {
  481.  public:
  482.   KeyPressPanel(UiP ui,int dpyNum,int viewportNum,const Xvars &xvars,
  483.         Window parent,
  484.         const Pos &pos,const Size &size,
  485.         void (*callback)(UiP,KeyPressPanel *,XEvent *),
  486.         const char *msg = NULL);
  487.   
  488.   virtual Boolean process_event(int dpyNum,XEvent *event);
  489.  
  490.  
  491.  private:
  492.   void (*callback)(UiP,KeyPressPanel *,XEvent *);
  493. };
  494.  
  495.  
  496.  
  497. class ButtonPanel: public TextPanel {
  498.  public:
  499.   ButtonPanel(UiP ui,int dpyNum,int viewportNum,const Xvars &xvars,
  500.           Window parent,
  501.           const Pos &pos,const Size &size,
  502.           void (*callback)(UiP,int,int),
  503.           const char *msg = NULL);
  504.   
  505.   virtual Boolean process_event(int dpyNum,XEvent *event);
  506.  
  507.  
  508.  private:
  509.   void (*callback)(UiP,int vNum,int button);
  510. };
  511.  
  512.  
  513.  
  514. class TogglePanel: public TextPanel {
  515.  public:
  516.   TogglePanel(UiP ui,int dpyNum,int viewportNum,const Xvars &xvars,
  517.           Window parent,
  518.           const Pos &pos,const Size &size,
  519.           void (*callback)(UiP,TogglePanel *,Boolean),
  520.           const char *msg);
  521.   
  522.   Boolean get_value() {return set;}
  523.   void set_value(Boolean);
  524.  
  525.   virtual Boolean process_event(int dpyNum,XEvent *event);
  526.  
  527.  
  528.  private:
  529.   Boolean set;
  530.   void (*callback)(UiP,TogglePanel *,Boolean);
  531. };
  532. #endif
  533.